/**
 * 灵活的锁
 * 
 * std::unique_lock  使用起来要比lock_guard更灵活，但是效率会第一点，内存的占用也会大一点
 * 参数：std::adopt_lock  表示互斥量已经被lock，不需要再重复lock。该互斥量之前必须已经lock，才可以使用该参数。 
 * 参数：std::defer_lock  在创建了unique_lock的对象时就不会自动加锁，那么就需要借助lock这个成员函数来进行手动加锁，当然也有unlock来手动解锁
 * 参数：std::try_to_lock 可以避免一些不必要的等待，会判断当前mutex能否被lock，如果不能被lock，可以先去执行其他代码。这个和adopt不同，不需要自己提前加锁
 * try_lock()  判断当前是否能lock，如果不能，先去执行其他的代码并返回false，如果可以，进行加锁并返回true
 * owns_lock() 查询是否拥有互斥量
 * release()  解除unique_lock和mutex对象的联系，并将原mutex对象的指针返回出来。如果之前的mutex已经加锁，需在后面自己手动unlock解锁
 * 
 */

#include <mutex>

class some_big_object
{};

void swap(some_big_object& lhs,some_big_object& rhs)
{}

class X
{
private:
    some_big_object some_detail;
    mutable std::mutex m;
public:
    X(some_big_object const& sd):some_detail(sd){}

    friend void swap(X& lhs, X& rhs)
    {
        if(&lhs==&rhs)
            return;
        std::unique_lock<std::mutex> lock_a(lhs.m,std::defer_lock);
        std::unique_lock<std::mutex> lock_b(rhs.m,std::defer_lock);
        std::lock(lock_a,lock_b);
        swap(lhs.some_detail,rhs.some_detail);
    }
};
std::mutex mlock;
void work1(int& s) {
	for (int i = 1; i <= 5000; i++) {
		std::unique_lock<std::mutex> munique(mlock, std::defer_lock);
		if (munique.try_lock() == true) {
			s += i;
		}
		else {
			// 处理一些没有共享内存的代码
		}
	}
}
void work1(int& s) {
	for (int i = 1; i <= 5000; i++) {
		std::unique_lock<std::mutex> munique(mlock);   // 这里是自动lock
		std::mutex *m = munique.release();
		s += i;
		m->unlock();
	}
}

int main()
{}
